/*
 * System.h
 *
 *  Created on: 22 Aug 2011
 *      Author: Allan
 */

#ifndef SYSTEM_H_
#define SYSTEM_H_

// C++ includes
#include <string>
#include <vector>
using namespace std;

// Eigen includes
#include <Eigen/Core>
using namespace Eigen;

// GeoReact includes
#include "Multiphase.h"
#include "ReactionSystem.h"
#include "CanonicalReactionSystem.h"

class System
{
public:
	System();
	
	System(const Multiphase& multiphase, const ReactionSystem& eReactions);
	
	System(const Multiphase& multiphase, const ReactionSystem& eReactions, const ReactionSystem& kReactions);
	
	void
	SetTemperature(double T);
	
	void
	SetPressure(double P);
	
	void
	SetComposition(const VectorXd& n);
	
	void
	SetComposition(const string& species, double val);
	
	void
	SetPrimarySpecies(const vector<string>& primarySpecies);
	
	void
	SetPrimarySpeciesByFrequency();
	
	void
	SetPrimarySpeciesByComposition();
	
	const Multiphase&
	GetMultiphase() const;
	
	const CanonicalReactionSystem&
	GetEquilibriumReactions() const;
	
	const ReactionSystem&
	GetKineticReactions() const;
	
	const double
	GetTemperature() const;
	
	const double
	GetPressure() const;
	
	const VectorXd&
	GetComposition() const;
	
	const Phase&
	GetPhase(const string& phasename) const;
	
	const VectorXd
	GetPhaseComposition(const string& phasename) const;
	
	const Index
	operator[](const string& species) const;
	
	const vector<Index>
	operator[](const vector<string>& species) const;
	
	const double
	Get(const string& quantity) const;
	
	const double
	Get(const string& quantity, const string& species) const;
	
	void
	OutputMultiphaseState(ostream& out = cout) const;
	
	void
	OutputReactionsState(ostream& out = cout) const;
	
	friend ostream&
	operator<<(ostream& out, const System& system);
	
private:
	/// The multiphase object of the system
	Multiphase multiphase;
	
	/// The equilibrium--controlled reactions
	CanonicalReactionSystem eReactions;
	
	/// The kinetically-controlled reactions
	ReactionSystem kReactions;
	
	/// The temperature (T) and pressure (P) of the system
	double T, P;
	
	/// The composition (n), activity (a), activity coefficient (g) and kinetic reaction rate (R) vectors
	VectorXd n, a, g, R;
	
private:
	void
	OutputMultiphase(ostream& out, const Multiphase& multiphase) const;
	
	void
	OutputReactionSystem(ostream& out, const ReactionSystem& reactions) const;
};



#endif /* SYSTEM_H_ */
